home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Turnbull China Bikeride
/
Turnbull China Bikeride - Disc 2.iso
/
STUTTGART
/
LANG
/
PROLOG
/
BP330
/
!BinPro330
/
progs
/
lconstr
< prev
next >
Wrap
Text File
|
1995-01-30
|
3KB
|
113 lines
% Program: linear implication based FD constraint solving
% Author: Paul Tarau, 1995
% simple cryptarithmetic puzzle solver
% a kind of "constraint solving with linear implication"
example1(
[s,e,n,d,m,o,r,e,y]=[S,E,N,D,M,O,R,E,Y],
[S,E,N,D]+
[M,O,R,E]=
[M,O,N,E,Y],
[s,e,n,d]+
[m,o,r,e]=
[ m,o,n,e,y]
).
% example from wamcc(clp) - adapted by
% Daniel Diaz - INRIA France, Original Source: P. Van Hentenryck's book
example2(
[a,b,c,d,e,f,g,h,i,j]=[A,B,C,D,E,F,G,H,I,J],
[B, A, I, J, J, A, J, I, I, A, H, F, C, F, E, B, B, J, E, A]+
[D, H, F, G, A, B, C, D, I, D, B, I, F, F, A, G, F, E, J, E]=
[G, J, E, G, A, C, D, D, H, F, A, F, J, B, F, I, H, E, E, F],
[b, a, i, j, j, a, j, i, i, a, h, f, c, f, e, b, b, j, e, a]+
[d, h, f, g, a, b, c, d, i, d, b, i, f, f, a, g, f, e, j, e]=
[g, j, e, g, a, c, d, d, h, f, a, f, j, b, f, i, h, e, e, f]
).
% Addition of two numbers
sum(As, Bs, Cs) :- sum(As, Bs, 0, Cs).
sum([A|As], [B|Bs], Carry, [C|Cs]) :- !,
add2digits(A,B,Carry,C,NewCarry),
sum(As, Bs, NewCarry, Cs).
sum([], Bs, 0, Bs) :- !.
sum(As, [], 0, As) :- !.
sum([], [B|Bs], Carry, [C|Cs]) :- !,
add1digit(B,Carry,C,NewCarry),
sum([], Bs, NewCarry, Cs).
sum([A|As], [], Carry, [C|Cs]) :- !,
add1digit(A,Carry,C,NewCarry),
sum([], As, NewCarry, Cs).
sum([], [], Carry, [Carry]).
add2digits(A,B,Carry,Result,NewCarry):-
bind(A),bind(B),
add_with_carry(10,A,B,Carry,Result,NewCarry).
add1digit(D,Carry,Result,NewCarry):-
bind(D),
add_with_carry(10,D,0,Carry,Result,NewCarry).
add_with_carry(Base,A,B,Carry,Result,NewCarry):-
S is A+B+Carry,
Result is S mod Base,
NewCarry is S // Base,
new_digit(Result).
reverse(Xs,Zs):-rev(Xs,[],Zs).
rev([],Ys,Ys).
rev([X|Xs],Ys,Zs):-rev(Xs,[X|Ys],Zs).
bind(A):-var(A),!,digit(A).
bind(_).
new_digit(A):-digit(A),!.
new_digit(_).
solve(As,Bs,Cs,Z):-
digit(0)-:digit(1)-:digit(2)-:digit(3)-:digit(4)-:digit(5)-:
digit(6)-:digit(7)-:digit(8)-:digit(9)-:
( sum(As,Bs,Cs),
Z>0
).
show_answer(Vars,Ns+Vs=Rs,As+Bs=Cs):-
write(Vars),nl,nl,
write(As),write(+),nl,
write(Bs),write(=),nl,
write(Cs),nl,nl,
write(Ns),write(+),nl,
write(Vs),write(=),nl,
write(Rs),nl,nl.
puzzle:-
init(Vars,Puzzle,Names),
Puzzle=(Xs+Ys=Zs),Zs=[Z|_],
reverse(Xs,As),
reverse(Ys,Bs),
reverse(Zs,Cs),
solve(As,Bs,Cs,Z),
show_answer(Vars,Names,Puzzle),
fail.
puzzle:-
write('no (more) answers'),nl,nl.
time(Goal):-
ctime(T1),
(Goal->true;true),
ctime(T2),
T is T2-T1,
write(time=T),nl,nl.
go:-
(init(X,Y,Z):-example1(X,Y,Z))-:
time(puzzle),
fail.
go:-
(init(X,Y,Z):-example2(X,Y,Z))-:
time(puzzle).